package slicer

import (
	"bufio"
	"io"
	"logSlicer/internal/pkg/log"
	"logSlicer/internal/pkg/util"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

var frontFile *os.File
var destFileMap map[string]*os.File
var GlobalChannel = make(chan Message, 16)

type Message struct {
	//不带路径的文件名
	keyNmae string
	//文件路径
	fileName string
	//需要写入的内容
	content string
}

func SrcFileDeal(fullPath string) {
	destFileMap = make(map[string]*os.File)
	file, err := os.Open(fullPath)
	if err != nil {
		log.Errorf("打开文件%s时出现异常。", fullPath)
	} else {
		readFileLineInfo(file)
		err = file.Close()
		if err != nil {
			log.Errorf("关闭文件时出现异常：", err.Error())
		}
	}
}

func readFileLineInfo(file *os.File) {
	rd := bufio.NewReader(file)
	for true {
		line, _, err := rd.ReadLine()
		if err != nil || io.EOF == err {
			break
		}
		lineInfo := string(line)
		flag := util.FindValueByKey("log.flag")
		messages := strings.Split(lineInfo, flag)

		which := util.FindValueByKey("log.which")
		index, err := strconv.Atoi(which)
		if len(messages) <= index {
			writeContentIntoFile(frontFile, lineInfo)
			continue
		}
		if err != nil {
			log.Errorf("将字符串%s转换为int类型异常。", which)
			continue
		}
		value := messages[index]
		cycleDealLine(value, lineInfo)
	}
}

func cycleDealLine(key string, content string) {
	desDir := util.FindValueByKey("log.des")
	name := strings.ReplaceAll(key, ":", "")

	fileName := filepath.Join(desDir, name)
	fileName = strings.ReplaceAll(fileName, ".", "")
	fileName = strings.TrimSpace(fileName)

	channelMessage := &Message{
		keyNmae:  key,
		fileName: fileName,
		content:  content,
	}
	GlobalChannel <- *channelMessage
}

func ProductThread() {
	log.Info("已经进入了生产者线程。")
	srcLogDir := util.FindValueByKey("log.src")
	for true {
		files := util.GetAllFilesOneDir(srcLogDir)
		if len(files) == 0 {
			time.Sleep(3 * time.Second)
			continue
		}
		log.Infof("在目录%s下发现文件：", srcLogDir)
		for _, value := range files {
			if len(value) != 0 {
				log.Info(value)
				fullPath := filepath.Join(srcLogDir, util.Separator, value)
				SrcFileDeal(fullPath)
				err := os.Remove(fullPath)
				if err != nil {
					log.Errorf("删除文件异常：%s", fullPath, err.Error())
				}
			}
		}
	}
}

func ConsumeThread() {
	log.Info("进入了消费者线程。")
	for true {
		cycleConsumeDate()
	}
}

func cycleConsumeDate() {
	data := <-GlobalChannel
	fileName := data.fileName
	name := data.keyNmae
	content := data.content

	exist := util.FileExist(fileName)
	if !exist {
		file, err := os.Create(fileName)
		if err != nil {
			log.Errorf("创建文件失败：%s，原因是：%s", fileName, err.Error())
			return
		} else {
			frontFile = file
		}
	}
	fd := destFileMap[name]
	if fd == nil {
		fd, err := os.OpenFile(fileName, os.O_APPEND, 0666)
		if err != nil {
			log.Errorf("打开文件%S出现异常：%s", fileName, err.Error())
			return
		}
		frontFile = fd
		destFileMap[name] = fd
	}
	fd = destFileMap[name]
	writeContentIntoFile(fd, content)
}

func writeContentIntoFile(file *os.File, content string) {
	if file == nil {
		return
	}
	err := util.WriteLines(file, content)
	if err != nil {
		log.Errorf("内容写文件异常：%s", err.Error())
	}
}
